package com.yz.aiks.multimodules;


import com.yz.base.boot.exception.AssertHelper;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import java.util.List;

/**
 * 处理读取redis信息工具类.
 * {@link redis.clients.jedis.Jedis}
 *
 * @author <a href="mailto:aiks_yuan@163.com">yuanz</a>
 * @date 2022-02-24 14:03
 * @since 1.0.0
 **/
public class JedisUtils extends AbstractJedisUtils {
    
    /**
     * 分布式锁成功标识.
     */
    private static final String LOCK_SUCC = "OK";
    
    /**
     * 删除缓存.
     *
     * @param key 不能为空
     * @return 返回删除数量
     */
    public long del(final String... key) {
        AssertHelper.notNull(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.del(key);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 删除hashmap类型的数据.
     *
     * @param key key定义
     * @param fields field
     * @return 返回删除数量
     */
    public long hDel(final String key, final String... fields) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        AssertHelper.notNull(key, REDIS_FIELD_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.hdel(key, fields);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 设置值.
     *
     * @param key 设置key
     * @param value 设置的值
     * @return 返回标识
     */
    public String set(final String key, final String value) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.set(key, value);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 设置值. list
     *
     * @param key 设置key
     * @param valueStrings 设置的值
     * @return 返回标识
     */
    public Long sadd(final String key, final String... valueStrings) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.sadd(key, valueStrings);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 设置过期时间
     *
     * @param key 设置key
     * @param seconds 过期时间 秒
     * @return 剩余过期时间
     */
    public Long expire(final String key, final long seconds) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.expire(key, seconds);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 设置值及时间.
     *
     * @param key key
     * @param value 值
     * @param seconds 时间秒
     * @return 返回标识
     */
    public String exSet(final String key, final String value, final Integer seconds) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        AssertHelper.notNull(seconds, REDIS_EXPIRE_TIME_NULL_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.setex(key, seconds, value);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 默认增量1.
     *
     * @param key key
     * @return 返回数量
     * @see JedisWriteUtils#incr(String, Long)
     */
    public long incr(final String key) {
        return incr(key, 1L);
    }
    
    /**
     * 增加值及步长.
     *
     * @param key key
     * @param increment 步长
     * @return 返回值
     */
    public long incr(final String key, final Long increment) {
        AssertHelper.notNull(increment, REDIS_INCREMENT_NULL_ERROR_KEY);
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.incrBy(key, increment);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 设置hash的值及时间.
     *
     * @param key key
     * @param field field
     * @param value 值
     * @param seconds 时间
     * @return 返回值
     */
    public long exHset(final String key, final String field, final String value, final Integer seconds) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        AssertHelper.notBlank(field, REDIS_FIELD_BLANK_ERROR_KEY);
        AssertHelper.notNull(seconds, REDIS_EXPIRE_TIME_NULL_ERROR_KEY);
        long result = hset(key, field, value);
        expire(key, seconds);
        return result;
    }
    
    /**
     * 设置hash值.
     *
     * @param key key
     * @param field field
     * @param value 值
     * @return 返回标识
     */
    public long hset(final String key, final String field, final String value) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        AssertHelper.notBlank(field, REDIS_FIELD_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.hset(key, field, value);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * hash设置自增默认增量1.
     *
     * @param key key
     * @param field field
     * @return 处理后的值
     * @see JedisWriteUtils#hIncr(String, String, Long)
     */
    public long hIncr(final String key, final String field) {
        return hIncr(key, field, 1L);
    }
    
    /**
     * hash类型数据增长.
     *
     * @param key key
     * @param field field
     * @param increment 步长
     * @return 返回值
     */
    public long hIncr(final String key, final String field, final Long increment) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        AssertHelper.notBlank(field, REDIS_FIELD_BLANK_ERROR_KEY);
        AssertHelper.notNull(increment, REDIS_INCREMENT_NULL_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.hincrBy(key, field, increment);
        } finally {
            jedis.close();
        }
    }
    /**
     * 设置key过期时间.
     *
     * @param key key
     * @param value 时长
     * @return 1表示不存在  0:表示存在.
     * @see Jedis#setnx(String, String)
     */
    public long setNx(final String key, final String value) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.setnx(key, value);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 如果不设置时间默认过期时间半小时.
     *
     * @param key 设置key值默认时间
     * @return 返回标识
     * @see JedisWriteUtils#expire(String, Integer)
     */
    public long expire(final String key) {
        return expire(key, SECOND_HALF_HOURS);
    }
    
    /**
     * 设置过去时间.
     *
     * @param key key
     * @param seconds 时间毫秒
     * @return 返回数据
     */
    public long expire(final String key, final Integer seconds) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        AssertHelper.notNull(seconds, REDIS_EXPIRE_TIME_NULL_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.expire(key, seconds);
        } finally {
            jedis.close();
        }
    }
    
    /**
     * 分布式锁命令.
     * set name value NX   [EX{表示过期时间秒}| PX{表示过期时间毫秒}] time
     * 这里设置锁时间为秒
     * NX 如果该key不存在返回OK
     * XX 如果该key存在时返回OK
     *
     * @param key key
     * @param value 值
     * @param seconds 时间
     * @return 返回成功与否标识
     */
    public boolean disLockSeconds(final String key, final String value, final Long seconds) {
        boolean lock = false;
        Jedis jedis = borrowConnection();
        try {
            String lockResult = jedis.set(key, value, new SetParams().nx().ex(seconds));
            if (LOCK_SUCC.equalsIgnoreCase(lockResult)) {
                lock = true;
            }
        } finally {
            jedis.close();
        }
        return lock;
    }
    
    /**
     * 分布式锁命令.
     * set name value NX   [EX{表示过期时间秒}| PX{表示过期时间毫秒}] time
     * <pre>set name value NX PX 3000 </pre>
     * 这里设置锁时间为秒
     * NX 如果该key不存在返回OK
     * XX 如果该key存在时返回OK
     *
     * @param key key
     * @param value 值
     * @param milliSecons 毫秒
     * @return 成功标识
     */
    public boolean disLockMilliSeconds(final String key, final String value, final Long milliSecons) {
        boolean lock = false;
        Jedis jedis = borrowConnection();
        try {
            String lockResult = jedis.set(key, value, new SetParams().nx().px(milliSecons));
            if (LOCK_SUCC.equalsIgnoreCase(lockResult)) {
                lock = true;
            }
        } finally {
            jedis.close();
        }
        return lock;
    }
    
    /**
     * 获取key值
     *
     * @param key key
     * @return 返回数据
     */
    public String get(String key) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.get(key);
        } finally {
            jedis.close();
        }
    }
    
    public List<String> srandmember(final String key, final int count) {
        AssertHelper.notBlank(key, REDIS_KEY_BLANK_ERROR_KEY);
        Jedis jedis = borrowConnection();
        try {
            return jedis.srandmember(key, count);
        } finally {
            jedis.close();
        }
    }
    
}
